/**
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *    
 *    Linking this library statically or dynamically with other modules 
 *    is making a combined work based on this library. Thus, the terms and
 *    conditions of the GNU General Public License cover the whole
 *    combination.
 *    
 *    As a special exception, the copyright holders of this library give 
 *    you permission to link this library with independent modules to 
 *    produce an executable, regardless of the license terms of these 
 *    independent modules, and to copy and distribute the resulting 
 *    executable under terms of your choice, provided that you also meet, 
 *    for each linked independent module, the terms and conditions of the 
 *    license of that module.  An independent module is a module which 
 *    is not derived from or based on this library.  If you modify this 
 *    library, you may extend this exception to your version of the 
 *    library, but you are not obligated to do so.  If you do not wish 
 *    to do so, delete this exception statement from your version.
 *
 *    Project: Financas Pessoais
 *    Author : Igor Salles
 */
package org.fp.db;

import com.mysql.jdbc.Statement;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.Level;

import java.util.logging.Logger;
import org.fp.logger.Jornal;

/**
 * Create the connection to a sqlite db and setit up. Its expect to work with
 * an existing database on the root of the project/jar. If the database doesnt
 * exists the connector will create one and return a conection.
 * </p>
 * Basic Usage is: 
 * <code>java.sql.Connection con = org.fp.db.Connections.getInstance();</code>
 *
 * @author Igor Salles
 * @since May 18, 2011
 */
public class Connections {
    /**/
    private Logger jornal = Jornal.getInstance();
    private static java.sql.Connection conn = null; 
    private String db_driver = null;
    private String db_url = null;
    private String db_user = null;
    private String db_pass = null;
    private String db_flag = null;
    private String db_name = null;
    private String db_port = null;
    private boolean db_autocommit = false;
    private boolean db_sqlite = false;
    private static boolean con_use = false;
    
    private Connections(){
        this.configure();
        this.initialize();
    }
    /**
     * Init a connection with the database.
     */
    private void initialize(){
        //vamos trabalhar com um banco sqlite?
        if (isSQLite()){
            //o banco ja existe?
            File f = new File(db_name);
            if (f.exists()){
                jornal.config("Arquivo " + f.getName() + " existe." );
                //System.out.println("File "+f.getName()+" existe.");
            }else{
                jornal.config("File "+f.getName()+" nao encontrado.");
                //System.out.println("File "+f.getName()+" nao encontrado.");
            }
            //existindo ou nao, o importante eh respeitar o classpath para o
            //arquivo de banco. a principio o db vai residir na raiz do projeto
            
            //comecaremos a proceder com a iniciacao da conecao com o banco
            try {
            //Carregando o classloader para a o connector jdbc sqlite
                
                
                jornal.config("Loading driver "+db_driver);
                Class.forName(db_driver);
                jornal.config("Connecting to DB "+db_url+db_name);
                conn = DriverManager.getConnection(db_url+db_name);
                jornal.config("Configurando autocommit to "+db_autocommit);
                conn.setAutoCommit(db_autocommit);
                                
            }catch(ClassNotFoundException e){
                jornal.log(Level.SEVERE,
                        "Problems loading driver driver "+db_driver,
                        e);                
            }catch(SQLException ex){
                jornal.log(Level.SEVERE,
                        "Cant Connect to DB URL "+db_url+db_name,
                        ex);
            }
//            try{
//            conn.close();
//            }catch(SQLException e){
//                e.printStackTrace();
//            }
        }
    }
    
    public synchronized void terminate(){
        if (conn == null){
            //all good connection dead
        }else if (con_use){
            try {
                conn.close();
            }catch (SQLException e){
                jornal.log(Level.SEVERE, "Fail to shutdown the connection.", e);
            }
        }
        
        
    }
    
    public static synchronized  Connection getInstance(){
        if(conn == null){
            //todo: cria conexao
            Connections cs = new Connections();
            return conn;           
        }
        return conn;
    }
    
    private void configure() {
        //configura variaveis de acordo com as propriedades
        //pegar o caminho real para o nosso arquivo de properties
        URL propPath = ClassLoader.getSystemResource("org/fp/files/db.properties");
        //cria o objeto para as propriedades
        Properties prop = new Properties();
        try {
            //carregar o arquivo de propriedades 
            prop.load(propPath.openStream());
        } catch (IOException e) {
            jornal.log(Level.SEVERE,
                    "Error trying to load propertie file.",
                    e);            
        }
        //agora vamos ver qual o tipo de db esperamos trabalhar
        if (prop.getProperty("db.provider").equalsIgnoreCase("sqlitejdbc")){
            db_sqlite = true;
            db_driver = prop.getProperty("db.connection.class");
            db_url = prop.getProperty("db.connection.url");
            db_name = prop.getProperty("db.name");
            db_autocommit = 
                    prop.getProperty("db.connection.autocommit").equalsIgnoreCase("true");
        }else if(prop.getProperty("db.provider").equalsIgnoreCase("mysqljdbc")) {
            //todo: configurar propriedades para mysql jdbc connection
        }else {
            //provider nao esperado entao 
            try {
            throw new ClassNotFoundException("Database provider not supported.");
            }catch(ClassNotFoundException e){
                //capturado minha propria excessao aqui para poder adicionar
                //depois no codigo final
                e.printStackTrace();
            }
        }//else if
   
    }//configure()
    
    public boolean isAutoCommit(){
        try{
            db_autocommit = conn.getAutoCommit();
        }catch(SQLException e){
            jornal.log(Level.SEVERE, "Impossible get autocommit status.", e);
        }
        return db_autocommit;
    }//isAutoCommit()
    
    public boolean isSQLite(){
        return db_sqlite;
    }
    
}//class
